<?php
/**
 * Created by PhpStorm.
 * Date: 2023/05/15
 * Time: 16:21
 * Desc: 抽奖算法
 */

namespace app\backend\services;

use App\backend\models\BigWheelLogModel;


class lotteryServices
{
    /**
     * 概率基数
     * @var int
     */
    private $total_chance = 10000;

    /**
     * 谢谢参与奖励
     * @var array
     */
    private $thanks_prize = [
        'id' => 0,
        'pid' => 0,
        'name' => '谢谢参与'
    ];

    /**
     * 奖品池
     * @var array
     */
    private $prize = [
        ['id' => 1, 'pid' => 11, 'name' => '一等奖', 'inventory' => 20, 'chance' => 500],
        ['id' => 2, 'pid' => 12, 'name' => '二等奖', 'inventory' => 40, 'chance' => 1000],
        ['id' => 3, 'pid' => 13, 'name' => '三等奖', 'inventory' => 80, 'chance' => 3000],
        ['id' => 4, 'pid' => 14,  'name' => '特等奖', 'inventory' => 20, 'chance' => 100]
    ];

    /**
     * 活动id
     * @var int
     */
    private $activity = 1;

    /**
     * Lottery constructor.
     */
    public function __construct(array $prize, int $activity)
    {
        if (!empty($prize)) {
            foreach ($prize as &$val) {
                $val['chance'] = $val['chance'] * 100;
            }
        }
        $this->prize = $prize;
        $this->activity = $activity;
    }

    /**
     * 重构奖池、重组概率
     * @return array
     */
    private function init_lottery_pond()
    {
        $award = [];
        //加入谢谢惠顾
        $now_chance = array_sum(array_column($this->prize, 'chance'));
        $remain_chance = $this->total_chance - $now_chance;
        $this->prize[] = ['id' => 0, 'pid' => 0, 'name' => '谢谢参与', 'inventory' => 0, 'chance' => $remain_chance];
        //重组概率
        $num = 0;
        foreach ($this->prize as $_v) {
            $num += $_v['chance'];
            $award[] = ['id' => $_v['id'], 'pid' => $_v['pid'],  'name' => $_v['name'], 'inventory' => $_v['inventory'], 'chance' => $num];
        }
        return $award;
    }

    /**
     * 获取抽奖结果
     * @return array
     */
    public function get_prize()
    {
        $award = $this->init_lottery_pond();
        $rand = mt_rand(1, $this->total_chance);
        $result = [];
        foreach ($award as $_k => $_v) {
            if ($_k == 0) {
                if ($rand > 0 && $rand <= $_v['chance']) {
                    $result = $_v;
                    break;
                }
            } else {
                if ($rand > $award[$_k - 1]['chance'] && $rand <= $_v['chance']) {
                    $result = $_v;
                    break;
                }
            }
        }
        $result = $this->filter($result);
        return $result;
    }

    /**
     * 获取抽奖结果 方法二
     * @return array
     */
    public function get_prize2()
    {
        $proArr = $this->init_lottery();
        $rid = 0;
        //概率数组的总概率精度
        $proSum = array_sum($proArr);
        //概率数组循环
        foreach ($proArr as $key => $proCur) {
            $randNum = mt_rand(1, $proSum);
            if ($randNum <= $proCur) {
                $rid = $key;
                break;
            } else {
                $proSum -= $proCur;
            }
        }
        unset($proArr);
        $data = $this->prize[$rid-1];
        $result = $this->filter($data);
        return $result;
    }

    /**
     * 重构奖池、重组概率
     * @return array
     */
    private function init_lottery()
    {
        //加入谢谢惠顾
        $now_chance = array_sum(array_column($this->prize, 'chance'));
        $remain_chance = $this->total_chance - $now_chance;
        $this->prize[] = ['id' => count($this->prize)+1 , 'pid' => 0, 'type' => 1, 'name' => '谢谢参与', 'inventory' => 0, 'chance' => $remain_chance];
        $proArr = array_column($this->prize, 'chance','id');
        return $proArr;
    }

    /**
     * 抽奖过滤回调函数
     * @param $result
     * @return array
     */
    private function filter($result)
    {
        //奖品总数限制
        if ($result['pid'] != 0) {
            //获取数据库剩余库存
            $yet_num = BigWheelLogModel::getInstance()->getCount(['prize_id' => $result['pid'],'activity_id' => $this->activity]);
            if ($yet_num >= $result['inventory']) {
                $result = $this->thanks_prize;
            }
        }
        //不暴露敏感信息
        unset($result['inventory'], $result['chance']);
        return $result;
    }

    private function __clone()
    {

    }


}
